<template>
    <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px" status-icon
        v-loading="editLoading">
        <el-form-item v-for="(column, index) in columns" :label="column.title" :prop="column.prop" :key="index">
            <el-input v-if="column.type === 'input'" v-model="ruleForm[column.key]" :placeholder="column.placeholder" />
            <el-input-tag
                v-else-if="column.type === 'tag'"
                v-model="ruleForm[column.key]"
                draggable
                placeholder="请输入标签，用','分割"
                delimiter=","
            />
            <RichText
                v-else-if="column.type === 'richtext'"
                :content="ruleForm[column.key]"
                :img-save-type="column.saveType"
                :changeContent="changeRichtext(column)"
                :enable-toolebar="column.enableToolbar"
                :disable-toolbar="column.disableToolbar"
            />
            <el-select-v2 v-else-if="column.type === 'select'" 
                v-model="ruleForm[column.key]" :loading="selectloading" 
                filterable clearable
                :multiple="column.multiple == 1 ? true : false"
                :remote="column.remote ? true : false" :remote-method="remoteMethod(column.remoteUrl, index)" 
                :options="column.selectOption" :placeholder="column.placeholder ? column.placeholder : '请选择'"
                >
                <template #empty>
                    <el-checkbox v-model="column.remote"> 搜索 </el-checkbox>
                </template>
            </el-select-v2>
            <el-date-picker v-else-if="column.type === 'date'" v-model="ruleForm[column.key]" type="date"
                label="column.title" :placeholder="column.placeholder ? column.placeholder : '请选择'" style="width: 100%" />
            <el-switch v-else-if="column.type === 'switch'" :active-value="column.switchOpen"
                :inactive-value="column.switchClose" v-model="ruleForm[column.key]" :active-color="column.switchOpenColor"
                :inactive-color="column.switchCloseColor" :active-text="column.switchOpenText"
                :inactive-text="column.switchCloseText" />
            <el-checkbox-group v-else-if="column.type === 'check'" v-model="ruleForm[column.key]">
                <el-checkbox v-for="(option, index) in column.selectOption" :label="option.value" name="option.label"
                    :key="column.key + index" />
            </el-checkbox-group>
            <el-tree-v2 ref="treeRef" class="treeSelectClass" v-else-if="column.type === 'treeSelect'"
                :props="{ value: 'value', label: 'label', children: 'children', disabled: 'disable' }"
                :data="column.selectOption" :height="200" :key="model + column.key" show-checkbox
                :default-checked-keys="ruleForm[column.key]" :default-expanded-keys="[]" />
            <el-radio-group v-else-if="column.type === 'radio'" v-model="ruleForm[column.key]">
                <el-radio v-for="(option, index) in column.selectOption" :label="option.value"
                    :key="column.label + index" />
            </el-radio-group>
            <el-input v-else-if="column.type === 'textarea'" :autosize="{ minRows: 2, maxRows: 10 }" :show-word-limit="true"
                v-model="ruleForm[column.key]" type="textarea" />
            <el-upload
                v-if="column.type === 'file'"
                :accept="column.accept"
                :action="column.saveType == 'local' ? column.url: UploadUrl"
                :name="column.key"
                :show-file-list="false"
                :headers="column.headers ? JSON.parse(column.headers): {}"
                :on-success="handleUploadSuccess(column)"
                :http-request="handleUploadUrl(column)"
                :ref="handleSetUploadRef(column)"
            >
                <img v-if="ruleForm[column.key]" :src="ruleForm[column.key]" style="width: 100%; height: 80px;" />
                <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            </el-upload>
            <div v-else-if="column.type === 'object'">
                <el-row>
                    <!-- <div class="" v-for="(item,okey) in ruleForm[column.key]" :key="'obj_key_' + okey">
                        {{item}}
                        {{okey}}:<el-input v-model="ruleForm[column.key][okey]" />
                    </div> -->
                    {{ ruleForm[column.key] }}
                    <div class="rowDis">
                        <div class="rowDis_div">
                            <div class="puting" v-for="(item, index) in inputList" :key="index">
                                <el-input style="width: 48.5%;" v-model="item.key" placeholder="键" />
                                <el-input style="width: 48.5%;" v-model="item.value" placeholder="值" />
                            </div>
                        </div>
                        <el-button type="primary" size="small" @click="addObject(column.key)" :icon="Plus"></el-button>
                        <el-button type="primary" size="small" @click="formatObject(column.key)">完成</el-button>
                    </div>
                </el-row>
            </div>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
            <el-button @click="closeEdit(ruleFormRef)">关闭</el-button>
        </el-form-item>
    </el-form>
</template>

<script lang="ts" setup>
import { reactive, ref, onMounted, VNode, VNodeRef } from "vue"
import { Plus } from '@element-plus/icons-vue'
import { ElTreeV2, ElSelectV2, UploadRawFile, UploadRequestOptions } from "element-plus"
import type { FormInstance, FormRules, UploadRequestHandler, UploadProps } from "element-plus"
import { getFormColumns, updateData, addData, getDetail, searchQuery } from "@/api/resources"
import { getUploadUrl, saveFileUrl, uploadFile } from '@/api/file';
import RichText from "@/components/RichText/index.vue"
import { getFileHash } from '@/utils'
/**
 * 自定义map
 */
type KeyValue = {
  key: any
  value: any
};

const uploadRef: Record<string, any> = {}
const editLoading = ref(false)
const emits = defineEmits(["closeForm"])            // 关闭表单的回调
const props = defineProps(["model", "formData", "new"])    // 获取表单数据
const formSize = ref("default")                     // 表单尺寸
const ruleFormRef = ref<FormInstance>()             // 表单实例
const treeRef = ref()                               // 树实例
let headers = ref([])
let inputList = reactive<KeyValue[]>([])            // 输入框列表
editLoading.value = true
onMounted(() => {
    // 加载完成后关闭加载动画
    editLoading.value = false

    if (ruleForm.value.id) {
        // id存在时，从服务器获取数据
        getDetail(props.model, ruleForm.value.id).then(({ data }) => {
            ruleForm.value = data
            console.log(ruleForm.value)
        })
    }
})

const ruleForm = ref()
let columns = ref()
let rules = ref(<FormRules><unknown>[])

ruleForm.value = props.formData


getFormColumns(props.model, props.new).then(({ data, code, ext } : any) => {
    if (code === 1) {
        columns.value = data.columns
        rules.value = data.rule
    }
})

let selectloading = ref(false)

const remoteMethod = (url: string, key: number) => {
    return (query: string) => {
        let column = columns.value[key]
        if (query) {
            selectloading.value = true
            searchQuery(url, query).then((res:any)=>{
                console.log(res.data)
                selectloading.value = false
                column.selectOption = res.data.map((item :any) => {
                    return {
                        'label': item[column.optionKey],
                        'value': item[column.optionVal]
                    }
                // return item.nickname.toLowerCase().includes(query.toLowerCase())
                })
            })
        } else {
            column.selectOption = []
        }
    }
}


const submitForm = async (formEl: FormInstance | undefined) => {
    let treeSelect = columns.value.filter((column: any) => {
        console.log(column)
        return column.type == 'treeSelect'
    })
    for(let i=0;i<treeSelect.length;i++){
      ruleForm.value[treeSelect[i].key] = treeRef.value[i]!.getCheckedKeys()
    }
    if (!formEl) return
    await formEl.validate((valid, fields) => {
        if (valid) {
            if (props.formData.id) {
                updateData(props.model, ruleForm.value).then(({ code, data } : any) => {
                    if (code === 1) {
                        closeEdit(formEl)
                        console.log("成功修改")
                    }
                })
            } else {
                addData(props.model, ruleForm.value).then(({ code, data } :any) => {
                    if (code === 1) {
                        closeEdit(formEl)
                        console.log("成功新增")
                    }
                })
            }
        } else {
            console.log('error submit!', fields)
        }
    })
}

const closeEdit = (formEl: FormInstance | undefined) => {
    console.log(formEl)
    emits("closeForm",)
}

const addObject = (key: string) => {
    if(!ruleForm.value[key]){
        ruleForm.value[key] = {}
    }
    for (let i in Object.keys(ruleForm.value[key])) {
        let obj = {
            key: Object.keys(ruleForm.value[key])[i],
            value: Object.values(ruleForm.value[key])[i]
        }
        inputList.push(obj)
    }
    console.log(inputList)
    let newobj = {
        key: '',
        value: ''
    }
    inputList.push(newobj)
}

const formatObject = (key: string) => {
    ruleForm.value[key] = {}
    inputList.map((item: any) => {
        if(item.key != ''){
            ruleForm.value[key][item.key] = item.value
        }
    })
    inputList.length = 0
    console.log(ruleForm.value[key])
}

// 上传文件配置
let UploadUrl = ref("")
const handleUploadSuccess = (column: any) => {
    return (res: any) => {
        console.log(res, 'handleUploadSuccess.res')
        ruleForm.value[column.key] = res
    }
}

/**
 * 处理本地上传
 * @param rawFile 文件
 */
const handleLocalUploadBefore: UploadRequestHandler = (option: UploadRequestOptions) => {
    return new Promise((resolve, reject) => {
        let file = option.file
        console.log(file, option)
        resolve(file)
    })
}

/**
 * 处理上传URL，根据类型区分OSS或本地上传
 */
const handleUploadUrl = (column: any) => {
    if(column.saveType == 'alioss'){
        return (option: UploadRequestOptions) => {
            return new Promise((resolve, reject) => { 
                let file = option.file
                getFileHash(file).then((md5: string) => {
                    console.log(md5, file);
                    getUploadUrl(file.name, md5, file.type).then(({data, ext, code}: any) => {
                        console.log(data, ext, 'getUploadUrl')
                        if(ext.status == 1) {
                            resolve(ext.url)
                            return 
                        }
                        console.log(data, ext, code)
                        UploadUrl.value =  data
                        fetch(data, {
                            method: "PUT",
                            body: file,
                            headers: {
                                'Content-Type': file.type
                            }
                        }).then(({ok, status}) => {
                            if(ok){
                                console.log(status)
                                saveFileUrl(ext.url, ext.id).then(res => {
                                    console.log(res)
                                    resolve(ext.url)
                                })
                            }
                        })
                    })
                })
            });
            
        }
    }else{
        UploadUrl.value = import.meta.env.VITE_BASE_API + column.url
        return handleLocalUploadBefore
    }
}
const handleSetUploadRef = (column: any) => {
    return (el: any) => {
        uploadRef[column.key] = el;
    }
}
/**
 * 富文本框改变时，将值保存到ruleForm中
 */
const changeRichtext = (column: any) => {
    return (value: string)=>{
        console.log(value, 'value')
        ruleForm.value[column.key] = value
    }
}
</script>

<style>
.treeSelectClass {
    width: 100%;
}

.rowDis_div {
    width: 90%;
}

.puting {
    display: flex;
    justify-content: space-between;
    margin-bottom: 10px;
}

.rowDis {
    display: flex;
    justify-content: space-between;
}
</style>